package arsmodeller.commands;

import org.eclipse.gef.commands.Command;

import arsmodeller.model.Connection;
import arsmodeller.model.Node;

public class ConnectionReconnectCommand extends Command {
	private Connection conn;
	private Node oldSource;
	private Node oldTarget;
	private Node newSource;
	private Node newTarget;

	public ConnectionReconnectCommand(Connection conn) {
		if (conn == null) {
			throw new IllegalArgumentException();
		}
		this.conn = conn;
		this.oldSource = conn.getSource();
		this.oldTarget = conn.getTarget();
	}

	public boolean canExecute() {
		if (newSource != null) {
			return checkSourceReconnection();
		} else if (newTarget != null) {
			return checkTargetReconnection();
		}
		return false;
	}

	private boolean checkSourceReconnection() {
		if (newSource == null)
			return false;
		else if (newSource.equals(oldTarget))
			return false;
		else if (!newSource.getClass().equals(oldTarget.getClass()))
			return false;
		return true;
	}

	private boolean checkTargetReconnection() {
		if (newTarget == null)
			return false;
		else if (oldSource.equals(newTarget))
			return false;
		else if (!oldSource.getClass().equals(newTarget.getClass()))
			return false;
		return true;
	}

	public void setNewSourceNode(Node sourceNode) {
		if (sourceNode == null) {
			throw new IllegalArgumentException();
		}
		this.newSource = sourceNode;
		this.newTarget = null;
	}

	public void setNewTargetNode(Node targetNode) {
		if (targetNode == null) {
			throw new IllegalArgumentException();
		}
		this.newSource = null;
		this.newTarget = targetNode;
	}

	public void execute() {
		if (newSource != null) {
			conn.reconnect(newSource, oldTarget);
		} else if (newTarget != null) {
			conn.reconnect(oldSource, newTarget);
		} else {
			throw new IllegalStateException("Should not happen");
		}
	}

	public void undo() {
		conn.reconnect(oldSource, oldTarget);
	}
}
